using System.Collections.Generic;
using UnityEngine.Profiling;
using FibMatrix.Task;
using UnityEngine;

namespace FibMatrix
{
	[FM_Mono.IgnoreGen]
	public class DownLoadBundlePipe : IResourceLoadPipe
	{
		public FMTask Handle(IResourcePipelineContext rawContext, out ResourceError error)
		{
			Profiler.BeginSample("DownLoadBundlePipe.Handle");
			error = ResourceError.None;
			ResourcePipelineContext context = rawContext as ResourcePipelineContext;
			AssetBundleLoadItem mainHint = context.item as AssetBundleLoadItem;
			List<BundleInfo> dependence = ResourceHelper.GetFixedFlatDependences(mainHint.bundleInfo);
			FMTaskList taskList = null;
			
			for (int i = 0, l = dependence != null ? dependence.Count : 0; i < l; ++i)
			{
				BundleInfo bundleInfo = dependence[i];
				// TODO, 包内文件没内容md5，可能版本不匹配
				// 虽然对urlMode赋值可以放到其构造函数里，但判断文件是否存在可能耗时，导致请求资源时的卡顿，放这里方便之后改为异步
				if (bundleInfo.urlMode == AssetBundleUrlMode.NotSure)
				{
					// 当前安卓是整包有所有资源，为了调试下载，即使有文件也走下载流程
					bundleInfo.urlMode = (!BundleLoadManager.instance.DoesBundleExist(bundleInfo.url, bundleInfo.md5) ||
					                      ResourceDevCfg.Instance.IsDebugStreamPlay())
						? AssetBundleUrlMode.Remote
						: AssetBundleUrlMode.Local;
				}

				if (bundleInfo.urlMode == AssetBundleUrlMode.Remote)
				{
					taskList = taskList ?? new FMTaskList("TaskList", false);
					taskList.Add(PooledAsyncFMTask.Allocate(bundleInfo, null, GenerateDownloadAsyncWork, GetDownloadAsyncWorkError, ProcessDownloadAsyncWorkResult));
				}
			}
			if (taskList != null)
			{
				taskList.asyncMode = true;
				taskList.Begin();
			}
			
			Profiler.EndSample();
			return taskList;
		}

		private static IAsyncBase GenerateDownloadAsyncWork(PooledAsyncFMTask task)
		{
			return ResourceDownloadManager.instance.DownloadSingle((task.context as BundleInfo).node);
		}

		private static ResourceError GetDownloadAsyncWorkError(PooledAsyncFMTask task, IAsyncBase asyncWork)
		{
			string errorDesc = asyncWork != null ? (asyncWork as IResourceDownloadTask).error : "NoRealTask";
			if (string.IsNullOrEmpty(errorDesc))
				return ResourceError.None;
			else
			{
				Debug.LogError(errorDesc);
				return ResourceError.DownloadAssetError;
			}
		}

		private static void ProcessDownloadAsyncWorkResult(PooledAsyncFMTask task, IAsyncBase asyncWork)
		{
			var bundleInfo = task.context as BundleInfo;
			{
				// 没必要把url从构建路径改为实际存储路径吧，反而使调试（同步加载包内，异步下载）的方式有问题
				// item.url = (asyncWork as IResourceDownloadTask).storagePath;
				bundleInfo.urlMode = AssetBundleUrlMode.Local;
			}
		}
	}
}